#ifndef SRC_TEST_CONTROLLER_MANAGER_H_
#define SRC_TEST_CONTROLLER_MANAGER_H_

#include <thread>
#include <condition_variable>
#include <map>
#include "test_controller/config.h"
#include "test_controller/ssh.h"

class Manager : public noncopyable,
  public std::enable_shared_from_this<Manager> {
 public:
  typedef std::shared_ptr<Manager> Ptr;
  explicit Manager(Config::Ptr config);
  virtual ~Manager();

 public:
  bool Start();

 private:
  struct DeviceInfo {
    typedef std::shared_ptr<DeviceInfo> Ptr;
    std::string sn;
    std::string name;
  };

  struct DeviceHostTask {
    typedef std::shared_ptr<DeviceHostTask> Ptr;
    Config::DeviceHost config;
    std::vector<DeviceInfo::Ptr> info;
    SSH::Ptr ssh;
  };

  struct ClientHostTask {
    typedef std::shared_ptr<ClientHostTask> Ptr;
    Config::ClientHost config;
    SSH::Ptr ssh;
  };

  DeviceHostTask::Ptr CreateDeviceHostTask(
    Config::DeviceHost &device_host_config);

  ClientHostTask::Ptr CreateClientHostTask(
    Config::ClientHost &client_host_config);

  void DeviceThreadFunction(DeviceHostTask::Ptr task);
  void ClientThreadFunction(ClientHostTask::Ptr task);

  bool GetPDNS(const std::string &sn, int port,
               std::string &mapping_ip, int &mapping_port);
  std::string CreateDeviceServiceConfig(DeviceHostTask::Ptr task);
  std::string CreateClientSimulatorConfig(ClientHostTask::Ptr task);
  bool WaitProgram(SSH::Ptr ssh, const char *system, const char *workpath,
                   const char *name, const char *type);

 private:
  Config::Ptr config_;
  std::mutex mutex_;
  std::condition_variable cond_;
  std::map<int, DeviceHostTask::Ptr> device_host_task_map_;
  std::map<int, ClientHostTask::Ptr> client_host_task_map_;
};

#endif  // SRC_TEST_CONTROLLER_MANAGER_H_



